package com.zzyl.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.Constants;
import com.zzyl.dto.UserLoginRequestDto;
import com.zzyl.entity.Member;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.MemberMapper;
import com.zzyl.properties.JwtTokenProperties;
import com.zzyl.service.*;
import com.zzyl.utils.JwtUtil;
import com.zzyl.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MemberServiceImpl implements MemberService {

    private static final List<String> DEFAULT_NICKNAME_PREFIX = List.of("生活更美好", "大桔大利", "日富一日", "好柿开花", "柿柿如意", "一椰暴富", "大柚所为", "杨梅吐气", "天生荔枝");

    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private ContractService contractService;
    @Autowired
    private MemberElderService memberElderService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private WechatService2 wechatService2;
    @Autowired
    private JwtTokenProperties jwtTokenProperties;

    /**
     * 根据id查询用户
     *
     * @param id 用户id
     * @return 用户信息
     */
    @Override
    public Member getById(Long id) {
        return memberMapper.selectById(id);
    }

    /**
     * 分页查询用户列表
     *
     * @param page     当前页码
     * @param pageSize 每页数量
     * @param phone    手机号
     * @param nickname 昵称
     * @return 分页结果
     */
    @Override
    public PageResponse<MemberVo> page(Integer page, Integer pageSize, String phone, String nickname) {
        PageHelper.startPage(page, pageSize);
        Page<Member> listPage = memberMapper.page(phone, nickname);

        PageResponse<MemberVo> pageResponse = PageResponse.of(listPage, MemberVo.class);

        pageResponse.getRecords().forEach(memberVo -> {
            List<ContractVo> contractVos = contractService.listByMemberPhone(memberVo.getPhone());
            memberVo.setIsSign(contractVos.isEmpty() ? "否" : "是");
            List<OrderVo> orderVos = orderService.listByMemberId(memberVo.getId());
            memberVo.setOrderCount(orderVos.size());
            List<MemberElderVo> memberElderVos = memberElderService.listByMemberId(memberVo.getId());
            List<String> collect = memberElderVos.stream().map(m -> m.getElderVo().getName()).collect(Collectors.toList());
            memberVo.setElderNames(String.join(",", collect));
        });
        return pageResponse;
    }

    /**
     * 小程序端用户登录
     * @return
     */
    @Override
    public LoginVo customerLogin(UserLoginRequestDto loginDto) {
        if (StrUtil.isEmpty(loginDto.getCode()) || StrUtil.isEmpty(loginDto.getPhoneCode())) {
            throw new BaseException(BasicEnum.PARAMETER_MISSING);
        }
        //1. 调用微信服务器获取微信用户的唯一标识openId
        String openId = wechatService2.getOpenid(loginDto.getCode());
        //2. 调用微信服务器获取授权访问令牌
        String accessToken = wechatService2.getWxAccessToken();
        //3. 调用微信服务器获取用户手机号
        String wxPhoneNumber = wechatService2.gettWxPhoneNumber(accessToken, loginDto.getPhoneCode(), openId);
        //4. 调用数据服务层根据openId获取用户信息
        Member member = memberMapper.getByOpenId(openId);
        //4.1 如果用户信息不存在 , 新增用户
        if (member == null) {
            member = new Member();
            member.setPhone(wxPhoneNumber);
            // 微信用户昵称 , 前缀+手机号后四位
            member.setName(getNickName((wxPhoneNumber)));
            member.setAvatar("https://inews.gtimg.com/om_bt/OGlQWfsaAoKkuCcMZ2o9IVEPqd-72DQy5EAN02XBHUwfYAA/641");
            member.setOpenId(openId);
            member.setGender(0);
            memberMapper.save(member);
        } else {
            //4.2 如果用户信息存在 , 判断信息有没有修改过, 如果修改过更新数据
            if (!StrUtil.equals(member.getPhone(), wxPhoneNumber)) {
                member.setPhone(wxPhoneNumber);
                memberMapper.update(member);
            }
        }
        //5. 生成token令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(Constants.JWT_USERID, member.getId());
        claims.put(Constants.JWT_USERNAME, member.getName());
        String jwt = JwtUtil.createJWT(jwtTokenProperties.getSecretKey(), getOffsetDays(jwtTokenProperties.getTtl()), claims);

        //6. 封装数据返回到微信小程序
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(jwt);
        loginVo.setNickName(member.getName());

        return loginVo;
    }

    /**
     * 将秒值转化为天
     *
     * @param ttl
     * @return
     */
    private int getOffsetDays(Integer ttl) {
        Long days = Convert.convertTime(ttl, TimeUnit.SECONDS, TimeUnit.DAYS);
        return days.intValue();
    }

    /**
     * 根据手机号随机生成用户昵称
     *
     * @param wxPhoneNumber
     * @return 前缀+手机号后四位
     */
    private String getNickName(String wxPhoneNumber) {
        //获取用户昵称前缀
        String prefix = DEFAULT_NICKNAME_PREFIX.get(RandomUtil.randomInt(DEFAULT_NICKNAME_PREFIX.size()));
        // 获取用户昵称后缀
        String suffix = StrUtil.subSuf(wxPhoneNumber, 7);
        return prefix + suffix;
    }
}
